#include "HY1C_out.h"
int loadl1_hic( filehandle *l1file, instr *input, l1str *l1rec,l1rec_HY1C *data_hic,int iscan){
    static double radeg = RADEG;
    static int   landmask = 0;
    static int   bathmask = 1;
    static int32_t  sensorID = -999;
    static int32_t    nwvis;
    static float *Fobar;
    static float *Tau_r;
    static float *k_oz;
    static float *aw;
    static float *bbw;
    int status;
    int32_t ip, ipb, ib, iw, ix;
    double  hour;
    double  esdist;
    double *rvs;
    double temp;
    l1rec->nbands=8;
    l1rec->year=(data_hic->year);
    l1rec->day=(data_hic->day);
    l1rec->msec=(data_hic->msec);
    int32_t    nbands   = l1rec->nbands;
    int32_t    nbandsir = l1rec->nbandsir;
    float Lambda_tmp[8]={412,443,490,520,565,670,750,865};
    float Tau_r_tmp[8];
    float k_oz_tmp[8];
    float Fobar_tmp[8];
    Fobar_tmp[1] = 173.373;
    Fobar_tmp[2] = 191.164;
    Fobar_tmp[3] = 197.719;
    Fobar_tmp[4] = 183.485;
    Fobar_tmp[5] = 180.421;
    Fobar_tmp[6] = 149.643;
    Fobar_tmp[7] = 126.776;
    Fobar_tmp[8] = 95.022;
//
// Rayleigh optical thickness
//
    Tau_r_tmp[1] = 3.011E-01;
    Tau_r_tmp[2] = 2.298E-01;
    Tau_r_tmp[3] = 1.575E-01;
    Tau_r_tmp[4] = 1.236E-01;
    Tau_r_tmp[5] = 8.750E-02;
    Tau_r_tmp[6] = 4.340E-02;
    Tau_r_tmp[7] = 2.740E-02;
    Tau_r_tmp[8] = 1.540E-02;
//
// Ozone absorption (/cm]
//
    k_oz_tmp[1] = 6.380E-03;
    k_oz_tmp[2] = 5.500E-03;
    k_oz_tmp[3] = 2.394E-02;
    k_oz_tmp[4] = 4.973E-02;
    k_oz_tmp[5] = 1.121E-01;
    k_oz_tmp[6] = 4.527E-02;
    k_oz_tmp[7] = 9.640E-03;
    k_oz_tmp[8] = 2.580E-03;
    /* Get correction for Earth-Sun distance and apply to Fo  */
//    HY1C_out("%d\n",*(l1rec->year));
    esdist = esdist_(l1rec->year,l1rec->day,l1rec->msec);
    l1rec->fsol = pow(1.0/esdist,2);
    for (iw=0; iw<nbands; iw++) {

        l1rec->iwave [iw] = Lambda_tmp[iw];
        l1rec->fwave [iw] = Lambda_tmp[iw];
        l1rec->Tau_r [iw] = Tau_r_tmp [iw];
        l1rec->k_oz  [iw] = k_oz_tmp  [iw];
        l1rec->Fobar [iw] = Fobar_tmp [iw];
        l1rec->Fo    [iw] = l1rec->Fobar[iw] * l1rec->fsol;
        get_f0_thuillier_ext(l1rec->iwave[iw],BANDW,&l1rec->Fonom[iw]);
    }

    if (sensorID != l1rec->sensorID) {
        sensorID = l1rec->sensorID;

        if (rdsensorinfo(l1rec->sensorID,l1rec->input->evalmask,NULL,NULL) != l1rec->nbands) {
            HY1C_out("-E- %s : Unable to read sensor file\n",__FILE__);
            exit(1);
        }
//        rdsensorinfo(l1rec->sensorID,l1rec->input->evalmask,"Lambda",(void **) &Lambda);
//        rdsensorinfo(l1rec->sensorID,l1rec->input->evalmask,"Fobar", (void **) &Fobar);
//        rdsensorinfo(l1rec->sensorID,l1rec->input->evalmask,"Tau_r", (void **) &Tau_r);
//        rdsensorinfo(l1rec->sensorID,l1rec->input->evalmask,"k_oz",  (void **) &k_oz);
//        rdsensorinfo(l1rec->sensorID,l1rec->input->evalmask,"aw",    (void **) &aw);
//        rdsensorinfo(l1rec->sensorID,l1rec->input->evalmask,"bbw",   (void **) &bbw);
//        nwvis = rdsensorinfo(l1rec->sensorID,l1rec->input->evalmask,"NbandsVIS",  NULL);

        HY1C_out("Loading land mask file from %s\n", input->land);

        if (b128_msk_init(input->land,landmask) != 0) {
            HY1C_out("-E- %s : Unable to initialize land mask\n",__FILE__);
          //  exit(1);
        }

//        HY1C_out("Loading bathymetry mask file from %s\n", input->water);

        if (b128_msk_init(input->water,bathmask) != 0) {
           HY1C_out("-E- %s : Unable to initialize bath mask\n",__FILE__);
//            exit(1);
        }

 //       HY1C_out("Loading ice mask file from %s\n", input->icefile);

        if (ice_mask_init(input->icefile,(int)(*l1rec->year),
                          (int)(*l1rec->day), input->ice_threshold) != 0) {
  //          HY1C_out("-E- %s : Unable to initialize ice mask\n",__FILE__);
          //  exit(1);
        }

    }


    /* Apply vicarious cross-calibration gains */

//    for (ix=0; ix<input->xcal_nwave; ix++) {
//        if ((input->xcal_opt[ix] & XCALRVS) != 0) {
//            if ((ib = bindex_get(input->xcal_wave[ix])) < 0) {
//                HY1C_out("-E- %sline %d: xcal wavelength %f does not match sensor\n",
//                     __FILE__,__LINE__,input->xcal_wave[ix]);
//             //   exit(1);
//            };
//            rvs = get_xcal(l1rec, XRVS, l1rec->iwave[ib]);
//            for (ip=0;ip<l1rec->npix; ip++) {
//                ipb  = ip*NBANDS+ib;
//                if (l1rec->Lt[ipb] > 0.0 && l1rec->Lt[ipb] < 1000.0)
//                  //  l1rec->Lt[ipb] /= rvs[ip];
//                  l1rec->Lt[ipb] /=1.0;
//            }
//        }
//    }

    l1rec->npix=data_hic->npix;
    l1rec->nscans=data_hic->nscans;
    l1rec->lon=twoD2oneD(data_hic->lon,iscan,data_hic->npix2);
    l1rec->lat=twoD2oneD(data_hic->lat,iscan,data_hic->npix2);
    l1rec->solz=twoD2oneD(data_hic->solz,iscan,data_hic->npix2);
    l1rec->sola=twoD2oneD(data_hic->sola,iscan,data_hic->npix2);
    l1rec->senz=twoD2oneD(data_hic->senz,iscan,data_hic->npix2);
    l1rec->sena=twoD2oneD(data_hic->sena,iscan,data_hic->npix2);
    l1rec->delphi=l1rec->sena;
    l1rec->csolz=l1rec->sena;
    l1rec->csenz=l1rec->sena;
    l1rec->scattang=l1rec->sena;
    for (ip=0; ip<l1rec->npix; ip++) {

        /* Apply vicarious calibration */
//        for (iw=0; iw<nbands; iw++) {
//            ipb = ip*NBANDS+iw;
//            if (l1rec->Lt[ipb] > 0.0 && l1rec->Lt[ipb] < 1000.0) {
//             //   l1rec->Lt[ipb] *= input->gain   [iw];
//              //  l1rec->Lt[ipb] += input->offset [iw];
//                l1rec->Lt[ipb] *= 1.0;
//                l1rec->Lt[ipb] += 0.0;
//            }
//        }

        /* Enforce longitude convention */
//        if (!l1rec->navfail[ip]) {
//            if (l1rec->lon[ip] < -180.)
//                l1rec->lon[ip] += 360.0;
//            else if (l1rec->lon[ip] > 180.0)
//                l1rec->lon[ip] -= 360.0;
//        }


        /* Set land/bathymetry flags */
        if (b128_msk_get(l1rec->lat[ip],l1rec->lon[ip],landmask) != 0 && input->format != FMT_L3BIN) {
            l1rec->land[ip] = ON;
        }
        if (!l1rec->land[ip] &&
            b128_msk_get(l1rec->lat[ip],l1rec->lon[ip],bathmask) != 0) {
            l1rec->swater[ip] = ON;
        }
        if (!l1rec->land[ip] &&
            ice_mask(l1rec->lon[ip],l1rec->lat[ip]) != 0) {
            l1rec->ice[ip] = ON;
        }

        /* Force all pixels to water pixels */
        if (input->proc_ocean == 2) {
            l1rec->land[ip] = OFF;
        }

        /* Adjust lon/lat and view geom for terrain height */
        if (!l1file->terrain_corrected) {
          if (input->proc_land && !l1rec->navfail[ip]) {
//            get_dem_height_(input->demfile,
//                            &l1rec->lon [ip],
//                            &l1rec->lat [ip],
//                            &l1rec->senz[ip],
//                            &l1rec->sena[ip],
//                            &l1rec->height[ip],
//                            (int32_t *) &status);
            if (status != 0) {
              HY1C_out("-E- %s line %d: error reading DEM file.\n",
                     __FILE__,__LINE__);
              return(1);
            }
          } else
            l1rec->height[ip] = 0.0;
        }

        /* Set sea surface temperature and salinity, and seawater optical properties */
        for (iw=0; iw<nbands; iw++) {
            ipb = ip*NBANDS+iw;
            l1rec->sw_n [ipb] = 1.334;
        l1rec->sw_a [ipb] = l1rec->aw [iw];
            l1rec->sw_bb[ipb] = l1rec->bbw[iw];
    }
        if (input->outband_opt >= 2) {
            for (iw=0; iw<nwvis; iw++) {
                ipb = ip*NBANDS+iw;
            l1rec->sw_a [ipb] = aw_spectra (l1rec->fwave[iw],BANDW);
                l1rec->sw_bb[ipb] = bbw_spectra(l1rec->fwave[iw],BANDW);
            }
    }
        if (!l1rec->land[ip]) {
            l1rec->sstref[ip] = get_sstref(input->sstfile,l1rec->lon[ip],l1rec->lat[ip],(int)(*l1rec->day));
            l1rec->sssref[ip] = get_sssref(input->sssfile,l1rec->lon[ip],l1rec->lat[ip],(int)(*l1rec->day));
            if (l1rec->sstref[ip] > BAD_FLT && l1rec->sssref[ip] > BAD_FLT && input->seawater_opt > 0) {
              for (iw=0; iw<nwvis; iw++) {
                ipb = ip*NBANDS+iw;
            l1rec->sw_n [ipb] = seawater_nsw(l1rec->fwave[iw],l1rec->sstref[ip],l1rec->sssref[ip],NULL);
            l1rec->sw_bb[ipb] = seawater_bb (l1rec->fwave[iw],l1rec->sstref[ip],l1rec->sssref[ip]);
          }
        }
        } else {
            l1rec->sstref[ip] = BAD_FLT;
            l1rec->sssref[ip] = BAD_FLT;
    }
        seawater_set(l1rec);

        /* Compute relative azimuth */
        l1rec->delphi[ip] = l1rec->sena[ip] - 180.0 - l1rec->sola[ip];
        if (l1rec->delphi[ip] < -180.)
            l1rec->delphi[ip] += 360.0;
        else if (l1rec->delphi[ip] > 180.0)
            l1rec->delphi[ip] -= 360.0;

        /* Precompute frequently used trig relations */
        l1rec->csolz[ip] = cos(l1rec->solz[ip]/radeg);
        l1rec->csenz[ip] = cos(l1rec->senz[ip]/radeg);

        /* Scattering angle */
        temp   = sqrt((1.0-l1rec->csenz[ip]*l1rec->csenz[ip])*(1.0-l1rec->csolz[ip]*l1rec->csolz[ip]))
               * cos(l1rec->delphi[ip]/radeg);
        l1rec->scattang[ip] = acos(MAX(-l1rec->csenz[ip]*l1rec->csolz[ip] + temp,-1.0))*radeg;
    }

    /* add ancillary data */
  //  if ( setanc(l1rec, input) != 0 )
 //       return(1);

    if (input->windspeed > -999)
        for (ip=0; ip<l1rec->npix; ip++)
            l1rec->ws[ip] = input->windspeed;
    if (input->windangle > -999)
        for (ip=0; ip<l1rec->npix; ip++)
            l1rec->wd[ip] = input->windangle;
    if (input->pressure > -999)
        for (ip=0; ip<l1rec->npix; ip++)
            l1rec->pr[ip] = input->pressure;
    if (input->ozone > -999)
        for (ip=0; ip<l1rec->npix; ip++)
            l1rec->oz[ip] = input->ozone;
    if (input->watervapor > -999)
        for (ip=0; ip<l1rec->npix; ip++)
            l1rec->wv[ip] = input->watervapor;
    if (input->relhumid > -999)
        for (ip=0; ip<l1rec->npix; ip++)
            l1rec->rh[ip] = input->relhumid;


    /* add atmospheric components that do not depend on Lt */

    for (ip=0; ip<l1rec->npix; ip++) {

        /* ------------------------------------------------ */
        /* Ocean processing                                 */
        /* ------------------------------------------------ */
        if ((input->proc_ocean != 0) && !l1rec->land[ip]) {

        if (input->ocrvc_opt == 0)
                atmocor1(l1rec,ip);

            /* set the smile_delta field */
            radcor(l1rec,ip,0);

            /* set polarization correction */
            polcor(l1rec,ip);

            /* add surface reflectance */
            get_rhos(l1rec,ip);

            /* assign uncertainty on Lt if not already set by sensor-specific i/o */
            for (iw=0; iw<nbands; iw++) {
                ipb = ip*NBANDS+iw;
                if (l1rec->Lt_unc[ipb] < BAD_FLT+1) {
                l1rec->Lt_unc[ipb] = (l1rec->Lt[ipb]-l1rec->Lr[ipb])*input->gain_unc[iw];
                }
            }
        }

        /* ------------------------------------------------ */
        /* Land Processing                                  */
        /* ------------------------------------------------ */
        else if (input->proc_land && l1rec->land[ip]) {
            atmocor1_land(input,l1rec,ip);
            radcor(l1rec,ip,1);
            get_rhos(l1rec,ip);
        }

        /* ------------------------------------------------ */
        /* General Processing                               */
        /* ------------------------------------------------ */
        else {
            for (ib=0; ib<NBANDS; ib++) {
                ipb = ip*NBANDS+ib;
                l1rec->Lr      [ipb] = 0.0;
                l1rec->t_sol   [ipb] = 1.0;
                l1rec->t_sen   [ipb] = 1.0;
                l1rec->tg_sol[ipb] = 1.0;
                l1rec->tg_sen[ipb] = 1.0;
                l1rec->t_o2    [ipb] = 1.0;
                l1rec->t_h2o   [ipb] = 1.0;
                l1rec->polcor  [ipb] = 1.0;
                l1rec->radcor  [ipb] = 0.0;
            }
    }

    }

    /* set masks and flags */
    if ( setflags(input, l1rec) == 0 )
        return(1);

    setflagbits(1,l1rec,NULL,-1);

    return (0);
}

